﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Aioms.Model;
using Aioms.Models;
using Furion.DynamicApiController;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using SqlSugar;
using SqlSugar.Extensions;

namespace Aioms.Controllers
{
    /// <summary>
    /// 首页面板
    /// </summary>
    [DynamicApiController]
    public class DashboardController
    {
        private readonly ISqlSugarClient db; // 核心对象：拥有完整的SqlSugar全部功能
        public DashboardController(ISqlSugarClient sqlSugarClient)
        {
            this.db = sqlSugarClient;
        }

        /// <summary>
        /// 我的任务
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="epid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostWoderenwu([FromForm] long eid, [FromForm] long epid)
        {
            JObject data = new();
            data.Add("daibanjihua", await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid && wo.Status == "未开始").Where($"FIND_IN_SET({epid}, epids)").CountAsync());
            data.Add("daibanweixiu", await db.Queryable<NrWorkOrder>().Where(wo => wo.Eid == eid && wo.Status == "未开始").Where($"FIND_IN_SET({epid}, epids)").CountAsync());
            data.Add("jinrishangbao", await db.Queryable<NoticeRepair>().Where(nr => nr.Sbepid == epid).Where(nr => nr.TroubleTime.Date == DateTime.Now.Date).CountAsync());
            // 报修完成和计划完成
            int bxwc = await db.Queryable<NrWorkOrder>().Where(wo => wo.Eid == eid && wo.Status == "已完成").Where(wo => wo.SjEndTime.Date == DateTime.Now.Date).CountAsync();
            int tpwc = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid && wo.Status == "已完成").Where(wo => wo.SjEndTime.Date == DateTime.Now.Date).CountAsync();
            data.Add("jinriwancheng", bxwc + tpwc);
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 设备故障
        /// </summary>
        /// <param name="eid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostShebeiguzhang([FromForm] long eid)
        {
            JObject data = new();
            data.Add("taishu", await db.Queryable<NoticeRepair>().Where(nr => nr.Eid == eid).Where(nr => nr.TroubleTime.Date == DateTime.Now.Date).GroupBy(nr => nr.Dvid).Select(nr => nr.Dvid).CountAsync());
            data.Add("cishu", await db.Queryable<NoticeRepair>().Where(nr => nr.Eid == eid).Where(nr => nr.TroubleTime.Date == DateTime.Now.Date).CountAsync());
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 设备停机
        /// </summary>
        /// <param name="eid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostShebeitingji([FromForm] long eid)
        {
            JObject data = new();
            data.Add("taishu", await db.Queryable<NoticeRepair>().Where(nr => nr.Eid == eid && nr.IsHalt == 1).Where(nr => nr.TroubleTime.Date == DateTime.Now.Date).GroupBy(nr => nr.Dvid).Select(nr => SqlFunc.AggregateCount(nr.Id)).CountAsync());

            List<NrWorkOrder> nrworkorders = await db.Queryable<NrWorkOrder>()
                .Mapper(wo => wo.NoticeRepair, wo => wo.NpId, wo => wo.NoticeRepair.Id)
                .Where(wo => wo.Eid == eid)
                .Where(wo => wo.NoticeRepair.IsHalt == 1)
                .Where(wo => wo.SjEndTime.Date == DateTime.Now.Date)
                .Where(wo => wo.Status == "已完成").ToListAsync();
            double shishu_total = 0;
            foreach (var nrworkorder in nrworkorders)
            {
                shishu_total += (nrworkorder.SjEndTime - nrworkorder.NoticeRepair.TroubleTime).TotalHours;
            }
            data.Add("shishu", Math.Round(shishu_total, 0));
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 计划任务占比
        /// </summary>
        /// <param name="eid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostJihuarenwuzhanbi([FromForm] long eid)
        {
            DateTime begintime = DateTime.Now;
            DateTime endtime = DateTime.Now;

            JObject data = new();

            data.Add("baoyangjihua", await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "保养工单").Where(wo => wo.BeginTime.Date == DateTime.Now.Date).CountAsync());
            data.Add("dianjianjihua", await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "点检工单").Where(wo => wo.BeginTime.Date == DateTime.Now.Date).CountAsync());
            data.Add("xunjianjihua", await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "巡检工单").Where(wo => wo.BeginTime.Date == DateTime.Now.Date).CountAsync());


            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 预防性维护计划完成率
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="rt"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostYufangxingweihujihuawanchenglv([FromForm] long eid)
        {
            DateTime begintime = DateTime.Now;
            DateTime endtime = DateTime.Now;

            JObject data = new();
            int baoyangjihua_total = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "保养工单").CountAsync();
            int dianjianjihua_total = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "点检工单").CountAsync();
            int xunjianjihua_total = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "巡检工单").CountAsync();


            int baoyangjihua = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "保养工单").Where(wo => wo.Status == "已完成").Where(wo => wo.SjEndTime.Date == DateTime.Now.Date).CountAsync();
            int dianjianjihua = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "点检工单").Where(wo => wo.Status == "已完成").Where(wo => wo.SjEndTime.Date == DateTime.Now.Date).CountAsync();
            int xunjianjihua = await db.Queryable<TpWorkOrder>().Where(wo => wo.Eid == eid).Where(wo => wo.Type == "巡检工单").Where(wo => wo.Status == "已完成").Where(wo => wo.SjEndTime.Date == DateTime.Now.Date).CountAsync();

            try
            {
                data.Add("baoyangjihua", baoyangjihua_total == 0 ? 0 : (double)baoyangjihua / baoyangjihua_total * 100);
                data.Add("dianjianjihua", dianjianjihua_total == 0 ? 0 : (double)dianjianjihua / dianjianjihua_total * 100);
                data.Add("xunjianjihua", xunjianjihua_total == 0 ? 0 : (double)xunjianjihua / xunjianjihua_total * 100);
            }
            catch (Exception e)
            {
                data.Add("baoyangjihua", 0);
                data.Add("dianjianjihua", 0);
                data.Add("xunjianjihua", 0);
                UnifyContext.Fill(new { Message = e.Message });
            }

            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 消息提醒
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="epid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostXiaoxitixing([FromForm] long eid, [FromForm] long epid)
        {
            List<Message> messages = await db.Queryable<Message>().Where(msg => msg.Eid == eid)
                .WhereIF(epid != 0, msg => msg.Epid == epid)
                .Where(msg => msg.Created.Date == DateTime.Now.Date)
                .ToListAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = messages,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 任务状态
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="epid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostRenwuzhuangtai([FromForm] long eid, [FromForm] long epid)
        {
            List<TpWorkOrder> workorders = await db.Queryable<TpWorkOrder>()
                .Where(wo => wo.Eid == eid)
                .WhereIF(epid != 0, $"FIND_IN_SET({epid}, epids)")
                //.Where(wo => wo.Type == "巡检工单")
                .Where(wo => wo.Status == "已完成")
                .ToListAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = workorders,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        ///  巡检路线地图
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="ilid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostInspectionlineditu([FromForm] long eid, [FromForm] long ilid)
        {
            JArray data = new();
            List<InspectionPoint> inspectionpoints = await db.Queryable<InspectionPoint>()
                .Where(ip => ip.Eid == eid)
                .Where(ip => ip.Ilid == ilid)
                .ToListAsync();
            foreach (var inspectionpoint in inspectionpoints)
            {
                JObject joip = new();
                string name = inspectionpoint.Name;
                string position = inspectionpoint.Position;
                int device_count = 0;
                bool hastrouble = false;
                Dictionary<string, int> trouble_device = new();
                if (!string.IsNullOrEmpty(inspectionpoint.Dvids))
                {
                    List<long> dvids = JArray.Parse(inspectionpoint.Dvids).ToObject<List<long>>();
                    List<Device> devices = await db.Queryable<Device>().Where(d => dvids.Contains(d.Id)).ToListAsync();
                    foreach (var device in devices)
                    {
                        if (device.Status == "故障")
                        {
                            hastrouble = true;
                            trouble_device.Add($"{device.Number}-{device.Name}", await db.Queryable<NoticeRepair>().Where(nr => nr.Eid == eid && nr.Dvid == device.Id).CountAsync());
                        }
                    }
                    device_count = dvids.Count;
                }
                joip.Add("name", name);
                joip.Add("position", position);
                joip.Add("device_count", device_count);
                joip.Add("hastrouble", hastrouble);
                joip.Add("trouble_devices", JObject.FromObject(trouble_device));
                data.Add(joip);
            }

            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        ///  区域地图
        /// </summary>
        /// <param name="eid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostAreaditu([FromForm] long eid)
        {
            JArray data = new();

            List<Area> areas = await db.Queryable<Area>()
                .Where(a => a.Eid == eid)
                .Where(a => a.IsDel == 0)
                .ToListAsync();
            foreach (var area in areas)
            {
                JObject joip = new();
                string name = area.Name;
                string position = area.Longitude + "," + area.Latitude;
                int device_count = 0;
                bool hastrouble = false;
                Dictionary<string, int> trouble_device = new();
                List<Device> devices = await db.Queryable<Device>().Where(d => d.Eid == eid && d.Aeid == area.Id).ToListAsync();
                device_count = devices.Count;
                if (devices?.Count > 0)
                {
                    foreach (var device in devices)
                    {
                        if (device.Status.Equals("故障"))
                        {
                            hastrouble = true;
                            trouble_device.Add($"{device.Number}-{device.Name}", await db.Queryable<NoticeRepair>().Where(nr => nr.Eid == eid && nr.Dvid == device.Id).CountAsync());
                        }
                    }
                }
                joip.Add("name", name);
                joip.Add("position", position);
                joip.Add("device_count", device_count);
                joip.Add("hastrouble", hastrouble);
                joip.Add("trouble_devices", JObject.FromObject(trouble_device));
                data.Add(joip);
            }

            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }
    }
}
